﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataTier;
using DbLayer;
using System.Threading;

namespace BusinessTier
{

    public class ReservationCtr
    {

        private static ReservationCtr _instance = null;
        private IDbReservation _dbReservation = DbReservation.Instance;
        private StationCtr _stationCtr = StationCtr.Instance;

        private ReservationCtr()
        {
        }

        public static ReservationCtr Instance
        {

            get
            {

                if (_instance == null)
                {
                    _instance = new ReservationCtr();
                }

                return _instance;

            }

        }

        public bool AddReservation(Customer customer, Route route)
        {

            Reservation reservation = new Reservation();
            reservation.Customer = customer;

            bool success = true;
            int index = 0;

            lock (this)
            {

                while (success && index < route.Connections.Count)
                {

                    Connection connection = route.Connections[index];
                    Station station = _stationCtr.GetStation(connection.To);

                    if (station != null)
                    {

                        if (_stationCtr.ReserveBattery(station))
                        {
                            reservation.AddPartReservation(station);
                        }
                        else
                        {
                            success = false;
                        }

                    }

                    index += 1;

                }

                if (success)
                {
                    _dbReservation.AddReservation(reservation);
                }
                else
                {
                    // Rollback
                }

            }

            return success;

        }

        public IList<Reservation> GetReservations(Customer customer)
        {
            return _dbReservation.GetReservations(customer.CustomerId);
        }

        public IList<Reservation> GetAllReservations()
        {
            return _dbReservation.GetAllReservations();
        }

        public void RemoveReservation(Reservation reservation)
        {

            lock (this)
            {

                Reservation theReservation = _dbReservation.GetReservation(reservation.ReservationNr);

                if (theReservation != null)
                {

                    foreach (PartReservation partReservation in theReservation.PartReservations)
                    {
                        Station station = _stationCtr.GetStation(partReservation.Station.Id);
                        _stationCtr.AddBattery(station);
                    }

                    _dbReservation.RemoveReservation(theReservation.ReservationNr);

                }

            }

        }

    }

}
